/**
 * 
 */
package com.douyu.ocean.connect.router.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.ocean.connect.router.api.model.TianxiaoConnectSession;
import org.ocean.connect.router.api.util.TxCcSessionKeyUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.baijia.commons.cache.CacheUtil;
import com.douyu.ocean.connect.router.result.BaseApiResult;
import com.douyu.ocean.connect.router.service.ConnectBindService;
import com.douyu.ocean.connect.router.service.MessageSendService;

import lombok.extern.slf4j.Slf4j;

/**
 * @author leiruiqi
 *
 */
@Service("connectBindService")
@Slf4j
public class ConnectBindServiceImpl implements ConnectBindService{

	@Value("${route.cc.url.remove}")
	private String removeApiUrl = "/connectStatus/removeSessionKey";
	
	
	//@Value("${route.cc.port}")
	//private String sendMessageApiDefaultPort = "80";
	
	//private String devicePrefix = "txcc_sid_";
	
	@Resource
	private MessageSendService messageSendService;
	
	//@Async
	@Override
	public void bindSession(TianxiaoConnectSession session) {
		doBizBeforeBind(session);
		try {
			String deviceKey = session.getBizType()+session.getDeviceId();
			
			CacheUtil.set(deviceKey,session.getSessionKey(),3600*12);
			CacheUtil.set(session.getSessionKey(), session,3600*12);
			
			log.info("set session succese key="+session.getSessionKey()+",ip="+session.getSessionIp());
		} catch (Exception e) {
			log.error("",e);
		}
	}
	
	//@Async
	@Override
	public void unbindSession(TianxiaoConnectSession session) {
		doBizBeforeUnBind(session);
		try {
			
			TianxiaoConnectSession oldSession = (TianxiaoConnectSession)CacheUtil.getValue(session.getSessionKey());
			if(oldSession == null){
				return;
			}
			if(StringUtils.equals(oldSession.getSessionId(),session.getSessionId())){
				String deviceKey = session.getBizType()+session.getDeviceId();
				CacheUtil.delete(deviceKey);
				CacheUtil.delete(session.getSessionKey());
				
			}
			
		} catch (Exception e) {
			log.error("",e);
		}
		
	}
	
	/**
	 * 绑定前处理业务
	 * @param session
	 */
	private void doBizBeforeBind(TianxiaoConnectSession session){
		String deviceKey = session.getBizType()+session.getDeviceId();
		String sessionKey = (String)CacheUtil.getValue(deviceKey);
		
		if(StringUtils.isNotBlank(sessionKey)){
			TianxiaoConnectSession oldsession = findBySessionKey(sessionKey);
			if(oldsession == null){
				return;
			}
			// ip 相等说明是同一台服务器，无需通知其它服务器让用户下线。
			if(!StringUtils.equals(oldsession.getSessionIp(), session.getSessionIp())) {
				//消息为空直接移除会话，因为是同一设备，默认同一设备只能代表一个在线的用户，一个设备有多个身份不合理，回导致a，b身份的用户，消息相互干扰
				String message = "";
				BaseApiResult baseResult = this.removeCCSession(oldsession,message);
				if(!baseResult.getCode().equals("1")){
					log.error("message send error ,msg = "+baseResult.getMsg());
				}
			}
			
		}
	}
	
	
	
	/**
	 * 解绑前处理业务
	 * @param session
	 */
	private void doBizBeforeUnBind(TianxiaoConnectSession session){
		
	}

	@Override
	public TianxiaoConnectSession findBySessionKey(String key) {
		Object o = null;
		try {
			//long startTime = System.currentTimeMillis();
			o = CacheUtil.getValue(key);
			//long endTime = System.currentTimeMillis();
			//logger.info("end find session from cache key="+key+" used time"+(endTime-startTime));
		} catch (Exception e) {
			log.error("",e);
		}
		
		if(o!= null){
			return (TianxiaoConnectSession)o;
		}
		return null;
	}

	@Override
	public List<TianxiaoConnectSession> findAllUserBindSession(String bizType,String userId, String deviceDomain) {
		List<TianxiaoConnectSession> sessionList = new ArrayList<TianxiaoConnectSession>();
		String userKey = TxCcSessionKeyUtil.createTxSessionKeyUserId(bizType, userId);
		if(StringUtils.isNotBlank(deviceDomain)){
			userKey+=deviceDomain+TxCcSessionKeyUtil.tx_session_separator;
		}
		log.info("[Redis] Get keys.key={}",userKey+"*");
		long start = System.currentTimeMillis();
		Set<String> keys = CacheUtil.getkeys(userKey+"*");
		log.info("[Redis] Get key cost={}",(System.currentTimeMillis() - start));
		List<Object> olist = CacheUtil.getMulti(new ArrayList<String>(keys));
		if(CollectionUtils.isNotEmpty(olist)){
			for(Object o:olist){
				sessionList.add((TianxiaoConnectSession)o);
			}
		}
		return sessionList;
	}


	@Override
	public List<TianxiaoConnectSession> findAllUserBindSessionByPrefix(String bizType, String userIdPrefix) {
		List<TianxiaoConnectSession> sessionList = new ArrayList<TianxiaoConnectSession>();
		
		List<String> sessionKeyList = findAllUserBindSessionKeyByPrefix(bizType,userIdPrefix);
		if(CollectionUtils.isEmpty(sessionKeyList)){
			return sessionList;
		}
		List<Object> olist = CacheUtil.getMulti(sessionKeyList);
		if(CollectionUtils.isNotEmpty(olist)){
			for(Object o:olist){
				sessionList.add((TianxiaoConnectSession)o);
			}
		}
		return sessionList;
	}

	@Override
	public List<String> findAllUserBindSessionKeyByPrefix(String bizType, String userIdPrefix) {
		List<String> sessionKeyList = new ArrayList<String>();
		String userKey = TxCcSessionKeyUtil.createTxSessionKeyUserIdPrefix(bizType, userIdPrefix);
		log.info("[Redis] Get keys.key=",userKey+"*");
		long start = System.currentTimeMillis();
		Set<String> keys = CacheUtil.getkeys(userKey+"*");
		log.info("[Redis] Get key cost={}",(System.currentTimeMillis() - start));
		if(!CollectionUtils.isEmpty(keys)){
			sessionKeyList.addAll(keys);
		}
		return sessionKeyList;
	}

	private BaseApiResult removeCCSession(TianxiaoConnectSession session, String messageJsonStr){
		RestTemplate restTemplate = new RestTemplate();
		MultiValueMap<String, Object> params = new LinkedMultiValueMap<String, Object>();

		
	    params.add("sessionKey", session.getSessionKey());
	    params.add("sessionId", messageJsonStr);
	    params.add("message", messageJsonStr);
	    String uri= "http://"+session.getSessionIp()+removeApiUrl;
		BaseApiResult sendresult = restTemplate.postForObject(uri, params, BaseApiResult.class);
		return sendresult;
	}
	
	/*private void messageBatchToCC(List<TianxiaoConnectSession> sessionList, String messageJsonStr){
		
		for(TianxiaoConnectSession session:sessionList){
			BaseResult result =  messageSendService.messageSend(session, messageJsonStr);
		}
		
		
	}*/
	
	public static void main(String[] args) {
		
		RestTemplate restTemplate = new RestTemplate();
		MultiValueMap<String, Object> params = new LinkedMultiValueMap<String, Object>();

		
	    params.add("sessionKey", "a");
	    params.add("sessionId", "a");
	    params.add("message", "a123");
	    String uri= "http://"+"127.0.0.1"+":"+"17081"+"/connectStatus/removeSessionKey";
		BaseApiResult sendresult = null;
		try {
			sendresult = restTemplate.postForObject(uri, params, BaseApiResult.class);
		} catch (Exception e) {
			System.out.println(e);
		}
		System.out.println(sendresult);
	}

	@Override
	public boolean addBindAttribute(TianxiaoConnectSession session) {
		try {
			String deviceKey = session.getBizType()+session.getDeviceId();
			
			String sessionKey = (String)CacheUtil.getValue(deviceKey);
			if(StringUtils.isNotBlank(sessionKey)){
				TianxiaoConnectSession tempsession = (TianxiaoConnectSession)CacheUtil.getValue(sessionKey);
				if(tempsession !=null&&StringUtils.equals(session.getSessionId(), tempsession.getSessionId())){					
					CacheUtil.set(session.getSessionKey(), session,3600*12);
					CacheUtil.set(deviceKey,session.getSessionKey(),3600*12);
					return true;
				}
			}

			log.info("set session succese key="+session.getSessionKey()+",ip="+session.getSessionIp());
		} catch (Exception e) {
			log.error("",e);
		}
		return false;
	}
	

}
